////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                   ///
///                     Driver for Real Time Clock                           ///
///                                                                          ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
///                 used when PIC loses power and DS1307 run from 3V BAT     ///
///               - Disable squarewave output                                ///
///                                                                          ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   ///
///                                                                          ///
/// ds1307_get_date(day,mth,year,dow)               Get the date             ///
///                                                                          ///
/// ds1307_get_time(hr,min,sec)                     Get the time             ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

//#define DEVICE_SDA  PIN_c4
//#define DEVICE_SCL  PIN_c3

//#use i2c(master, sda=DEVICE_SDA, scl=DEVICE_SCL, force_hw)


int8 bin2bcd(int8 binary_value);
int8 bcd2bin(int8 bcd_value);


//----DS137 init--------------------------------------------------//
void ds1307_init()
{
   int8 seconds;// = 0;
   output_float(device_SCL);
   output_float(device_SDA);
   delay_ms(1);
   i2c_start();
   i2c_write(0xD0);      // dia chi va cua DS1307 va` ghi du lieu
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xD1);      // dia chi va cua DS1307 va` doc du lieu
   seconds = bcd2bin(i2c_read(0)); // doc
   i2c_stop();

   seconds &= 0x7F;
   delay_ms(1);
   delay_ms(3);
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_write(bin2bcd(seconds) & 0x7f);
   //i2c_stop();
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x07);
   i2c_write(0x90);
   i2c_stop();

}


//----Set date time-----------------------------------------------//
void ds1307_set_date_time(int8 day, int8 mth, int8 year, int8 dow, int8 hr,
 int8 min, int8 sec)
{

  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);            // I2C write address
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));    // REG 0
  i2c_write(bin2bcd(min));    // REG 1
  i2c_write(bin2bcd(hr));     // REG 2
  i2c_write(bin2bcd(dow));    // REG 3
  i2c_write(bin2bcd(day));    // REG 4
  i2c_write(bin2bcd(mth));    // REG 5
  i2c_write(bin2bcd(year));   // REG 6
  i2c_write(0x80);            // REG 7 - Disable squarewave output pin
  i2c_stop();
}

//----Set time----------------------------------------------------//
void DS1307_set_time(int8 hr,int8 min, int8 sec)
{
  sec &= 0x7F;
  hr &= 0x3F;
  i2c_start();
  i2c_write(0xD0);            // I2C write address
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));    // REG 0
  i2c_write(bin2bcd(min));    // REG 1
  i2c_write(bin2bcd(hr));
  i2c_stop();
}

//----Get date----------------------------------------------------//
void ds1307_get_date(int8 &day, int8 &mth, int8 &year, int8 &dow)
{

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);            // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read(1) & 0x7f); ///// REG 3
  day  = bcd2bin(i2c_read(1) & 0x3f); ///// REG 4
  mth  = bcd2bin(i2c_read(1) & 0x1f); ///// REG 5
  year = bcd2bin(i2c_read(0));       ///// REG 6
  i2c_stop();
}

//----Get time----------------------------------------------------//
void ds1307_get_time(int8 &hr, int8 &min, int8 &sec)
{

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  //i2c_stop();              // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read(1) & 0x7f);
  //sec = i2c_read() & 0x7f;
  min = bcd2bin(i2c_read(1) & 0x7f);
  //min =i2c_read() & 0x7f;
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  //hr  = i2c_read(0) & 0x3f;
  i2c_stop();
}

/////////////////////////////////////////
void start_time()
{
   int8 seconds;
   i2c_start();
   i2c_write(0xD0);       // dia chi va cua DS1307 va` ghi du lieu
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xD1);       // dia chi va cua DS1307 va` doc du lieu
   seconds = i2c_read(0); // doc
   i2c_stop();

   seconds &= 0x7F;// s
   delay_ms(1);
   //delay_us(3);
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_write(seconds);
   i2c_stop();
}

/////////////
void stop_time()
{
int8 seconds;
 i2c_start();
   i2c_write(0xD0);       // dia chi va cua DS1307 va` ghi du lieu
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xD1);       // dia chi va cua DS1307 va` doc du lieu
   seconds = i2c_read(0); // doc
   i2c_stop();
seconds |= 0x80;
   //seconds &= 0x7f;
    delay_ms(1);
   //delay_us(3);
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_write(seconds);
   i2c_stop();

}

/////////////
int8 bin2bcd(int8 binary_value)
{
  int8 temp;
  int8 retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
   if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}



int8 bcd2bin(int8 bcd_value)
{
  int8 temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

////////////////////////////
Void write_ds1307(int8 address,int8 data)
{
  I2c_start();
  i2c_write(0xd0);            // I2C write address
  i2c_write(address);
  i2c_write(data);
  I2c_stop();

}

/////////////////
int8 read_ds1307(int8 address)
{  int8 data;
   I2c_start();
   i2c_write(0xd0);            // I2C write address
   i2c_write(address);
   I2c_stop();
   delay_us(1);
   I2C_start();

   i2c_write(0xd1);
   data = I2C_read(0);
   I2c_stop();
   return (data);
}

////////////////////////////
void enable_clock()
{
   write_ds1307(0x07,0x90);
}

//////////////////////
void disable_clock()
{
   write_ds1307(0x07,0x80);
}
